package nxu.it.controller;

import io.undertow.util.StatusCodes;

import nxu.it.dao.Impl.JdbiTodoServiceImpl;
import nxu.it.dao.TodoService;
import nxu.it.model.Todo;
import nxu.it.security.NeedLoginHandler;
import nxu.it.util.SecurityUtil;
import org.noear.solon.annotation.*;
import org.noear.solon.boot.web.MimeType;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.MethodType;
import org.noear.solon.core.handle.ModelAndView;

import java.util.*;

@Controller
public class TodoController {
    private static TodoService todoService = new JdbiTodoServiceImpl();

    private static int pageIndex = 0;
    private static int pageSize = 10;

    @Mapping(value = "/todo/list", method = MethodType.GET, produces = MimeType.TEXT_HTML_VALUE)
    @Before(NeedLoginHandler.class)
    public ModelAndView list(Context ctx) {
        int count = SecurityUtil.getCurrentUser(ctx)
                .map(currentUsername -> todoService.listByUserCount(currentUsername))
                .orElse(0);
        int offset = 0;
        if (ctx.queryString() != null && ctx.queryString().indexOf("next") >= 0 && count > 10) {
            pageIndex = pageIndex + 1;
        } else if (ctx.queryString() != null && ctx.queryString().indexOf("pre") >= 0) {
            if (pageIndex > 0)
                pageIndex = pageIndex - 1;
        } else {
            pageIndex = 0;
            pageSize = 10;
        }
        offset = pageIndex * 10;
        List<Todo> todoList = SecurityUtil.getCurrentUser(ctx)
                .map(currentUsername -> todoService.listByUser(currentUsername))
                .orElse(new ArrayList<>());
        if (offset + pageSize < count)
            todoList = todoList.subList(offset, offset + pageSize);
        else
            todoList = todoList.subList(offset, count);
        String username = SecurityUtil.getCurrentUser(ctx).orElse("");
        ModelAndView mv = new ModelAndView("todo/list.ftl");
        mv.put("todoList", todoList);
        mv.put("username", username);


        return mv;
    }

    @Mapping(value = "/todo/save", method = MethodType.POST, produces = MimeType.TEXT_HTML_VALUE)
    @Before(NeedLoginHandler.class)
    public void save(Context ctx, String content, String contenttype) {

        Todo todo = new Todo(content, contenttype);
        SecurityUtil.getCurrentUser(ctx)
                .ifPresent(username -> {
                    todo.setUsername(username);
                    todoService.save(todo);
                });
        ctx.redirect("/todo/list", StatusCodes.SEE_OTHER);
    }

    @Mapping(value = "/todo/check", method = MethodType.GET, produces = MimeType.TEXT_HTML_VALUE)
    @Before(NeedLoginHandler.class)
    public void check(Context ctx, int id) {
        SecurityUtil.getCurrentUser(ctx).ifPresent(username -> {
            todoService.checkByUser(id, username);
        });
        ctx.redirect("/todo/list", StatusCodes.SEE_OTHER);
    }

    @Mapping(value = "/todo/edit", method = MethodType.GET, produces = MimeType.TEXT_HTML_VALUE)
    @Before(NeedLoginHandler.class)
    public ModelAndView edit(Context ctx, int id) {
        Optional<String> currentUser = SecurityUtil.getCurrentUser(ctx);
        Optional<Todo> todoOpt = todoService.getByUser(id, currentUser.get());

        if (todoOpt.isEmpty()) {
            return new ModelAndView("todo/not-found.ftl");
        }
        ModelAndView mv = new ModelAndView("todo/edit.ftl");
        mv.put("todo", todoOpt.get());
        return mv;
    }

    @Mapping(value = "/todo/update", method = MethodType.POST, produces = MimeType.TEXT_HTML_VALUE)
    @Before(NeedLoginHandler.class)
    public void update(Context ctx, Todo todo) {
        Optional<String> currentUser = SecurityUtil.getCurrentUser(ctx);
        todoService.updateByUser(todo, currentUser.get());
        ctx.redirect("/todo/list", StatusCodes.SEE_OTHER);
    }

    @Mapping(value = "/todo/delete", method = MethodType.GET, produces = MimeType.TEXT_HTML_VALUE)
    @Before(NeedLoginHandler.class)
    public void delete(Context ctx, int id) {
        Optional<String> currentUser = SecurityUtil.getCurrentUser(ctx);
        todoService.deleteByUser(id, currentUser.get());
        ctx.redirect("/todo/list", StatusCodes.SEE_OTHER);
    }

}
